#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
package ${package}.config.filter;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import ${package}.utils.UUIDGenerator;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@Slf4j
public class LogPrintFilter implements Filter {
    private List<String> excludeUrlList;
    public LogPrintFilter(List<String> excludeUrlList){
        this.excludeUrlList = excludeUrlList;
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String url = httpServletRequest.getServletPath();
        ContentCachingRequestWrapper contentCachingRequestWrapper = new ContentCachingRequestWrapper(httpServletRequest);
        ContentCachingResponseWrapper contentCachingResponseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) servletResponse);
        long startTime = System.currentTimeMillis();
        try {
            filterChain.doFilter(contentCachingRequestWrapper, contentCachingResponseWrapper);
        } finally {
            long endTime = System.currentTimeMillis();
            if(CollectionUtils.isNotEmpty(excludeUrlList)){
                boolean match = pathMatch(url, excludeUrlList);
                if(!match){
                    String uuid = UUIDGenerator.generate();
                    log.info("request uuid={}, url={}, methodType={}, params={}", uuid, url, httpServletRequest.getMethod(), new String(contentCachingRequestWrapper.getContentAsByteArray()));
                    log.info("response uuid={}, params={}, cost={}ms", uuid, new String(contentCachingResponseWrapper.getContentAsByteArray()), endTime-startTime);
                }
            }else{
                String uuid = UUIDGenerator.generate();
                log.info("request uuid={}, url={}, methodType={}, params={}", uuid, url, httpServletRequest.getMethod(), new String(contentCachingRequestWrapper.getContentAsByteArray()));
                log.info("response uuid={}, params={}, cost={}ms", uuid, new String(contentCachingResponseWrapper.getContentAsByteArray()), endTime-startTime);
            }
            //这一行必须添加，否则就一直不返回
            contentCachingResponseWrapper.copyBodyToResponse();
        }
    }

    public boolean pathMatch(String url, List<String> excludeUrlList) {
        AntPathMatcher pathMatcher = new AntPathMatcher();
        boolean isMatch = excludeUrlList.stream()
                .anyMatch(pattern -> pathMatcher.match(pattern, url));
        return isMatch;
    }
}
